package array

// Sum of numbers
// 数组有一个有趣的属性，它的大小也属于类型的一部分，
// 如果你尝试将 [4]int 作为 [5]int 类型的参数传入函数，是不能通过编译的。
// 它们是不同的类型，就像尝试将 string 当做 int 类型的参数传入函数一样。
// 因为这个原因，所以数组比较笨重，大多数情况下我们都不会使用它。
// Go 的切片（slice）类型不会将集合的长度保存在类型中，因此它的尺寸可以是不固定的。
func Sum(numbers []int) int {
	sum := 0
	// for i := 0; i < 5; i++ {
	// 	// 使用 array[index] 语法来获取数组中指定索引对应的值。
	// 	sum += numbers[i]
	// }
	// 可以使用 range 语法来让函数变得更加整洁
	for _, number := range numbers {
		sum += number
	}
	return sum
}

// SumAll sums numbers in different slices into a result slice
func SumAll(numbersToSum ...[]int) (sums []int) {
	lengthOfNumbers := len(numbersToSum)

	// make 可以在创建切片的时候指定我们需要的长度和容量。
	sums = make([]int, lengthOfNumbers)
	for i, numbers := range numbersToSum {
		// 可以使用切片的索引访问切片内的元素，使用 = 对切片元素进行赋值。
		sums[i] = Sum(numbers)
	}
	return
}

// SumAllTails sum the tails numbers in each slice.
func SumAllTails(numbersToSum ...[]int) []int {
	var sums []int

	for _, numbers := range numbersToSum {
		if len(numbers) == 0 {
			sums = append(sums, 0)
		} else {
			// 使用语法 slice[low:high] 获取部分切片。如果在冒号的一侧没有数字就会一直取到最边缘的元素。
			// 在我们的函数中，我们使用 numbers[1:] 取到从索引 1 到最后一个元素。
			tail := numbers[1:]
			sums = append(sums, Sum(tail))
		}
	}

	return sums
}
